package svc.elib.analysis;

import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;

import jsc.correlation.KendallCorrelation;
import jsc.datastructures.PairedData;

import org.apache.commons.math3.stat.correlation.PearsonsCorrelation;
import org.apache.commons.math3.stat.correlation.SpearmansCorrelation;

import svc.elib.db.Author;
import svc.elib.db.Database;
import svc.elib.socnet.CentralityMetrics;
import svc.elib.socnet.EvolutionarySnapshots;
import svc.elib.socnet.Link;
import svc.elib.socnet.Net;
import svc.elib.socnet.SocConstructor;
import svc.elib.socnet.TrivialComponents;

/**
 * Checks the so called strength of weak ties hypothesis:
 *    there is a positive correlation between the strength of connection
 *    and the number of shared acquaintances
 *    
 * @author svc
 */
public class StrengthOfWeakTies {
	
	private static int shared(Author a, Author b, Net n) {
		int numCommons = 0;
		Collection<Author> bNeis = n.getGraph().getNeighbors(b);
		Iterator<Author> anit = n.getGraph().getNeighbors(a).iterator();
		while (anit.hasNext()) {
			Author anei = anit.next();
			if (bNeis.contains(anei)) 
				++numCommons;
		}
		
		return numCommons;
	}

	public static void analysis(Net net) {
		EvolutionarySnapshots es = new EvolutionarySnapshots(net);
		int startYear = es.getStartYear();
		Net[] snaps = es.getSnapshots();
		
		for (int i = 0; i < snaps.length; i++) {
			Net cSnap = snaps[i];
			int year = startYear + i;
			
			if (cSnap.getNumLinks() < 2)
				continue;
			
			Iterator<Link> lit = cSnap.getGraph().getEdges().iterator();
			double seq1[] = new double[cSnap.getNumLinks()];
			double seq2[] = new double[cSnap.getNumLinks()];
			int scnt = 0;
			
			while (lit.hasNext()) {
				Link l = lit.next();
				Author a1 = l.getSrc();
				Author a2 = l.getDst();
				int w = l.getWeight();
				seq1[scnt] = w;
				seq2[scnt] = shared(a1, a2, cSnap);
				++scnt;
			}
			
			SpearmansCorrelation sc = new SpearmansCorrelation();
			double scc = sc.correlation(seq1, seq2);
			
			PearsonsCorrelation pc = new PearsonsCorrelation();
			double pcc = pc.correlation(seq1, seq2);
			
			KendallCorrelation kc = new KendallCorrelation(new PairedData(seq1, seq2));
			double kcc = kc.getTestStatistic();
			
			System.out.println(year + ", " + scc + ", " + pcc + ", " + kcc);
		}
	}
	
	public static void analysisBetWeight(Net net) {
		EvolutionarySnapshots es = new EvolutionarySnapshots(net);
		int startYear = es.getStartYear();
		Net[] snaps = es.getSnapshots();
		
		for (int i = 0; i < snaps.length; i++) {
			Net cSnap = snaps[i];
			int year = startYear + i;
			
			if (cSnap.getNumLinks() < 2)
				continue;
			
			CentralityMetrics cm = new CentralityMetrics(cSnap);
			cm.computeBetweeness(false);
			
			Iterator<Link> lit = cSnap.getGraph().getEdges().iterator();
			double seq1[] = new double[cSnap.getNumLinks()];
			double seq2[] = new double[cSnap.getNumLinks()];
			int scnt = 0;
			
			while (lit.hasNext()) {
				Link l = lit.next();
				int w = l.getWeight();
				seq1[scnt] = w;
				seq2[scnt] = cm.getLinkBetweenness(l.getName());
				++scnt;
			}
			
			SpearmansCorrelation sc = new SpearmansCorrelation();
			double scc = sc.correlation(seq1, seq2);
			
			PearsonsCorrelation pc = new PearsonsCorrelation();
			double pcc = pc.correlation(seq1, seq2);
			
			KendallCorrelation kc = new KendallCorrelation(new PairedData(seq1, seq2));
			double kcc = kc.getTestStatistic();
			
			System.out.println(year + ", " + scc + ", " + pcc + ", " + kcc);
		}
	}
	
	public static void main(String[] args) 
		throws IOException
	{
		Database db = new Database("eLibData.csv", 1932, 2011);
		SocConstructor soc = new SocConstructor(db);
		Net net = soc.getNet();
		
		//analysis(net);
		analysisBetWeight(net);
		
		System.out.println("Removing trivial components... ");
		
		TrivialComponents tc = new TrivialComponents(net);
		tc.determine();
		tc.filter();
		
		analysisBetWeight(net);
		
		/*
		ConnectedComponents cs = new ConnectedComponents(net);
		cs.resolveComponents();
		
		Net largestComp = cs.getComponents().get(0);
		analysis(largestComp);
		*/
	}
}
 